<template>
  <div class="designer-container">
    <div class="toolbar">
      <h2>页面设计器</h2>
      <div class="actions">
        <el-input v-model="pageName" placeholder="页面名称" style="width: 200px;"></el-input>
        <el-button type="primary" @click="addComponent">+ 添加组件</el-button>
        <el-button type="success" @click="savePage">保存页面</el-button>
      </div>
    </div>

    <div class="designer-content">
      <!-- 组件库 -->
      <div class="component-library">
        <h4>组件库</h4>
        <div v-for="comp in componentLibrary" :key="comp.id" class="component-item" draggable="true"
             @dragstart="startDrag($event, comp)">
          <span>{{ comp.label }}</span>
        </div>
      </div>

      <!-- 画布 -->
      <div class="canvas-area"
           @dragover.prevent
           @dragenter="onDragEnter"
           @dragleave="onDragLeave"
           @drop="onCanvasDrop">
        <div v-if="layout.length === 0" class="canvas-drop-hint">
          请从组件库中拖拽组件到这里
        </div>
        <grid-layout
          :layout.sync="layout"
          :col-num="12"
          :row-height="30"
          :is-draggable="true"
          :is-resizable="true"
          :is-mirrored="false"
          :margin="[10, 10]"
          :vertical-compact="true"
          :prevent-collision="true"
          :use-css-transforms="true"
          @layout-updated="onLayoutUpdated">
          <grid-item
            v-for="item in safeLayout"
            :key="item.id"
            :x="item.x"
            :y="item.y"
            :w="item.w"
            :h="item.h"
            :i="item.id"
            @resized="onItemResized"
            @moved="onItemMoved">
            <div class="grid-item-content" @click="selectItem(item)">
              <div class="component-wrapper" :class="{ selected: selectedId === item.id }">
                <input v-if="item.type === 'input'" type="text" :placeholder="item.label" class="form-control">
                <button v-else-if="item.type === 'button'" class="form-control">{{ item.label }}</button>
                <label v-else-if="item.type === 'checkbox'" class="form-control">
                  <input type="checkbox"> {{ item.label }}
                </label>
                <select v-else-if="item.type === 'select'" class="form-control">
                  <option>{{ item.label }}</option>
                </select>
                <textarea v-else-if="item.type === 'textarea'" :placeholder="item.label" class="form-control"></textarea>
                <div v-else class="form-control">{{ item.label }}</div>
              </div>
              <el-button-group class="delete-btn">
                <el-button size="mini" type="danger" @click.stop="deleteComponent(item.id)">删除</el-button>
              </el-button-group>
            </div>
          </grid-item>
        </grid-layout>
      </div>

      <!-- 属性面板 -->
      <div class="property-panel">
        <h4>属性编辑</h4>
        <div v-if="selectedItem" class="property-form">
          <el-form label-width="80px" size="small">
            <el-form-item label="类型">
              <el-select v-model="selectedItem.type" disabled>
                <el-option label="输入框" value="input"></el-option>
                <el-option label="按钮" value="button"></el-option>
                <el-option label="复选框" value="checkbox"></el-option>
                <el-option label="下拉框" value="select"></el-option>
                <el-option label="文本框" value="textarea"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="标签">
              <el-input v-model="selectedItem.label"></el-input>
            </el-form-item>
            <el-form-item label="宽度">
              <el-input-number v-model="selectedItem.w" :min="1" :max="12"></el-input-number>
            </el-form-item>
            <el-form-item label="高度">
              <el-input-number v-model="selectedItem.h" :min="1" :max="20"></el-input-number>
            </el-form-item>
          </el-form>
        </div>
        <div v-else style="color: #999;">
          点击画布中的组件编辑属性
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { GridLayout, GridItem } from 'vue-grid-layout'
import { createPage } from '@/api/lowcode'

export default {
  name: 'Designer',
  components: {
    GridLayout,
    GridItem
  },
  data() {
    return {
      pageName: '',
      layout: [],
      selectedId: null,
      componentId: 0,
      isDropping: false, // 防止重复拖拽
      componentLibrary: [
        { id: 'input', label: '输入框', type: 'input' },
        { id: 'button', label: '按钮', type: 'button' },
        { id: 'checkbox', label: '复选框', type: 'checkbox' },
        { id: 'select', label: '下拉框', type: 'select' },
        { id: 'textarea', label: '文本框', type: 'textarea' }
      ]
    }
  },
  computed: {
    selectedItem() {
      return this.layout.find(item => item.id === this.selectedId)
    },
    // 确保 layout 中的所有组件都有完整的属性
    safeLayout() {
      return this.layout.map(item => this.ensureComponentProps(item))
    }
  },
  methods: {
    // 确保组件有完整的属性，防止 vue-grid-layout 修改导致属性变成 undefined
    ensureComponentProps(component) {
      return {
        id: component.id,
        x: typeof component.x === 'number' ? component.x : 0,
        y: typeof component.y === 'number' ? component.y : 0,
        w: typeof component.w === 'number' ? component.w : 6,
        h: typeof component.h === 'number' ? component.h : 2,
        type: component.type || 'input',
        label: component.label || '新组件',
        ...component // 保留其他属性
      }
    },
    startDrag(event, component) {
      event.dataTransfer.effectAllowed = 'copy'
      event.dataTransfer.dropEffect = 'copy'
      event.dataTransfer.setData('componentType', component.type)
      event.dataTransfer.setData('componentLabel', component.label)
      console.log('正在拖拽组件:', component)
    },
    addComponent() {
      const newComponent = {
        id: `item-${++this.componentId}`,
        x: 0,
        y: this.layout.length,
        w: 6,
        h: 2,
        type: 'input',
        label: '新组件'
      }
      this.layout.push(newComponent)
    },
    selectItem(item) {
      this.selectedId = item.id
    },
    deleteComponent(id) {
      this.layout = this.layout.filter(item => item.id !== id)
      if (this.selectedId === id) {
        this.selectedId = null
      }
    },
    onLayoutUpdated() {
      // 移除频繁输出的 console.log，减少性能压力
    },
    onItemResized() {
      // 不再强制更新，让 vue-grid-layout 自行处理
    },
    onItemMoved() {
      // 不再强制更新，让 vue-grid-layout 自行处理
    },
    onDragEnter(event) {
      event.preventDefault()
      event.currentTarget.classList.add('drag-over')
    },
    onDragLeave(event) {
      event.preventDefault()
      // 只有当鼠标真正离开画布时才移除样式
      if (event.currentTarget === event.target) {
        event.currentTarget.classList.remove('drag-over')
      }
    },
    onCanvasDrop(event) {
      event.preventDefault()
      event.stopPropagation()
      event.currentTarget.classList.remove('drag-over')
      
      const componentType = event.dataTransfer.getData('componentType')
      const componentLabel = event.dataTransfer.getData('componentLabel')
      
      console.log('拖拽组件较正:', { componentType, componentLabel })
      
      if (componentType && !this.isDropping) {
        this.isDropping = true
        
        // 计算需要的 x 和 y、位置，磨合之前存在的组件
        let maxY = 0
        // 添加安全检查，防止无限循环
        let validItemCount = 0
        const maxItemsToCheck = 100 // 限制检查数量，防止性能问题
        
        for (let i = 0; i < this.layout.length && validItemCount < maxItemsToCheck; i++) {
          const item = this.layout[i]
          // 更严格的检查
          if (item && 
              typeof item.y === 'number' && 
              typeof item.h === 'number' && 
              !isNaN(item.y) && 
              !isNaN(item.h)) {
            const itemBottomY = item.y + item.h
            if (itemBottomY > maxY) {
              maxY = itemBottomY
            }
            validItemCount++
          }
        }
        
        const newComponent = {
          id: `item-${++this.componentId}`,
          x: 0,
          y: maxY,  // 放在低一个位置，而不是会重叠
          w: 6,
          h: 2,
          type: componentType,
          label: componentLabel || '新组件'
        }
        console.log('输入样式的组件:', newComponent)
        // 使用 push 直接修改数组，这样 vue-grid-layout 自己会磨合
        this.layout.push(this.ensureComponentProps(newComponent))
        console.log('当前布局数量:', this.layout.length)
        
        // 使用 setTimeout 确保重置标志，而不是依赖 nextTick
        setTimeout(() => {
          this.isDropping = false
        }, 50)
      } else {
        console.warn('组件类型不存在或正在拖拽', { componentType, isDropping: this.isDropping })
      }
    },
    async savePage() {
      if (!this.pageName.trim()) {
        this.$message.error('请输入页面名称')
        return
      }
      if (this.layout.length === 0) {
        this.$message.warning('请至少添加一个组件')
        return
      }
      try {
        const pageData = {
          name: this.pageName,
          content: JSON.stringify(this.layout),
          description: '低代码生成的页面'
        }
        await createPage(pageData)
        this.$message.success('页面保存成功')
        this.$router.push('/lowcode/list')
      } catch (error) {
        this.$message.error('保存失败：' + (error.response?.data?.message || error.message))
      }
    }
  }
}
</script>

<style scoped>
.designer-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

.toolbar {
  background: white;
  padding: 15px;
  border-bottom: 1px solid #ddd;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.toolbar h2 {
  margin: 0;
  font-size: 18px;
}

.actions {
  display: flex;
  gap: 10px;
}

.designer-content {
  display: flex;
  flex: 1;
  overflow: hidden;
  gap: 10px;
  padding: 10px;
}

.component-library {
  width: 150px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  overflow-y: auto;
}

.component-library h4 {
  margin: 0 0 10px 0;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.component-item {
  padding: 8px;
  margin-bottom: 8px;
  background: #f0f9ff;
  border: 1px solid #b3d8ff;
  border-radius: 3px;
  cursor: move;
  font-size: 12px;
  text-align: center;
  user-select: none;
  transition: all 0.2s;
}

.component-item:hover {
  background: #e6f7ff;
  transform: scale(1.02);
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.canvas-area {
  flex: 1;
  background: white;
  border-radius: 4px;
  padding: 10px;
  overflow: auto;
  border: 2px dashed #ddd;
  min-height: 400px;
  position: relative;
}

.canvas-area.drag-over {
  border-color: #409eff;
  background-color: #f0f9ff;
}

.grid-item-content {
  position: relative;
  height: 100%;
  width: 100%;
}

.component-wrapper {
  width: 100%;
  height: 100%;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 5px;
  box-sizing: border-box;
}

.component-wrapper.selected {
  border: 2px solid #409eff;
  background: #f0f9ff;
}

.form-control {
  width: 100%;
  padding: 5px;
  border: 1px solid #ddd;
  border-radius: 2px;
  font-size: 12px;
}

.delete-btn {
  position: absolute;
  top: 2px;
  right: 2px;
  opacity: 0;
  transition: opacity 0.3s;
}

.grid-item-content:hover .delete-btn {
  opacity: 1;
}

.property-panel {
  width: 220px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  overflow-y: auto;
}

.property-panel h4 {
  margin: 0 0 10px 0;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.property-form {
  font-size: 12px;
}

.vue-grid-layout {
  background: #fafafa;
}

.vue-grid-item {
  border: 1px dashed #ddd;
  background: white;
}

.vue-grid-item.vue-grid-placeholder {
  background: #d3e8f7;
  opacity: 0.2;
  border: 1px dashed #409eff;
}

.canvas-drop-hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #999;
  font-size: 14px;
}
</style>
